﻿using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Scripting;
using Microsoft.Scripting.Ast;
using Microsoft.Linq.Expressions;

namespace DlrBasic.Parser.Ast
{
    class Input : Statement
    {
        DlrBasicExpression prompt;
        VariableOrCall[] variables;

        public Input(SourceSpan span, DlrBasicExpression prompt, VariableOrCall[] variables)
            : base(span)
        {
            this.prompt = prompt;
            this.variables = variables;
        }

        protected internal override Expression Generate(DlrBasicGenerator generator, StateMemberGenerator stateParameter, LambdaBuilder builder)
        {
            List<Expression> inputExpressions = new List<Expression>();

            if (prompt != null)
            {
                Expression print = Utils.Call(typeof(DlrBasicHelpers).GetMethod("Print"),
                    prompt.SourceSpan, Utils.CodeContext(), 
                    Expression.ConvertHelper(prompt.Generate(generator), typeof(Object)));
                inputExpressions.Add(print);
            }

            Expression[] variableTypes = new Expression[variables.Length];
            for (int i = 0; i < variableTypes.Length; i++)
            {
                variableTypes[i] = Expression.Constant(variables[i].GetVariableType(generator));
            }

            Expression inputCall = Utils.Call(typeof(DlrBasicHelpers).GetMethod("Input"),
                SourceSpan, Utils.CodeContext(),
                Expression.NewArrayHelper(typeof(Type), variableTypes), Expression.Constant(true));

            Expression tempVariable = builder.HiddenVariable(typeof(object[]), "inputArguments");
            Expression inputResult = Expression.Assign(tempVariable, inputCall);
            inputExpressions.Add(inputResult);

            for (int i = 0; i < variables.Length; i++)
            {
                Expression variableAssign = variables[i].GenerateAssign(
                    generator, Expression.ConvertHelper(Expression.ArrayIndex(tempVariable, Expression.Constant(i)),
                    variables[i].GetVariableType(generator)));
                inputExpressions.Add(variableAssign);
            }

            inputExpressions.Add(base.Generate(generator, stateParameter, builder));

            return Expression.Block(inputExpressions.ToArray());
        }
    }
}
